package com.javaweb.secondhand_trading.service.Impl;

import com.javaweb.secondhand_trading.Dto.ProductDto;
import com.javaweb.secondhand_trading.common.exception.BusinessException;
import com.javaweb.secondhand_trading.entity.Product;
import com.javaweb.secondhand_trading.entity.ProductImage;
import com.javaweb.secondhand_trading.mapper.ProductImageMapper;
import com.javaweb.secondhand_trading.mapper.ProductMapper;
import com.javaweb.secondhand_trading.service.ProductService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.math.BigDecimal;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

/**
 * 商品服务实现类
 * 实现商品相关的业务逻辑操作
 */
@Service // 标识这是一个Spring服务组件
public class ProductServiceImpl implements ProductService {

    // 依赖注入商品Mapper
    private final ProductMapper productMapper;

    // 依赖注入商品图片Mapper
    private final ProductImageMapper productImageMapper;

    /**
     * 构造器注入Mapper依赖
     * @param productMapper 商品数据访问接口
     * @param productImageMapper 商品图片数据访问接口
     */
    public ProductServiceImpl(ProductMapper productMapper, ProductImageMapper productImageMapper) {
        this.productMapper = productMapper;
        this.productImageMapper = productImageMapper;
    }

    /**
     * 添加商品（包含图片上传）
     * @param productDto 商品数据传输对象
     * @param images 商品图片文件列表
     * @return 保存后的商品实体
     * @throws BusinessException 业务异常
     */
    @Override
    @Transactional // 添加事务管理
    public Product addProduct(ProductDto productDto, List<MultipartFile> images) {
        // 创建商品实体并设置属性
        Product product = new Product();
        product.setUserId(productDto.getUserId());
        product.setTitle(productDto.getTitle());
        product.setPrice(new BigDecimal(String.valueOf(productDto.getPrice())));
        product.setDescription(productDto.getDescription());
        product.setStatus("available"); // 默认设置为可用状态

        // 插入商品记录到数据库
        productMapper.insert(product);

        // 如果有上传图片，则保存图片
        if (images != null && !images.isEmpty()) {
            List<ProductImage> productImages = saveProductImages(images, product.getProductId());
            product.setImages(productImages);
        }

        return product;
    }

    /**
     * 更新商品信息
     * @param productId 商品ID
     * @param productDto 商品数据传输对象
     * @param images 新的商品图片文件列表
     * @return 更新后的商品实体
     * @throws BusinessException 如果商品不存在或用户无权限修改
     */
    @Override
    @Transactional
    public Product updateProduct(Integer productId, ProductDto productDto, List<MultipartFile> images) {
        // 检查商品是否存在及权限
        Product existingProduct = productMapper.findById(productId);
        if (existingProduct == null || !existingProduct.getUserId().equals(productDto.getUserId())) {
            throw new BusinessException("商品不存在或无权修改");
        }

        // 更新商品信息
        existingProduct.setTitle(productDto.getTitle());
        existingProduct.setPrice(new BigDecimal(String.valueOf(productDto.getPrice())));
        existingProduct.setDescription(productDto.getDescription());
        existingProduct.setUserId(productDto.getUserId());
        existingProduct.setStatus(productDto.getStatus());

        // 更新数据库记录
        productMapper.update(existingProduct);

        // 处理图片更新：先删除旧图片，再保存新图片
        if (images != null && !images.isEmpty()) {
            productImageMapper.deleteByProductId(productId);
            List<ProductImage> productImages = saveProductImages(images, productId);
            existingProduct.setImages(productImages);
        }

        return existingProduct;
    }

    /**
     * 删除商品
     * @param productId 商品ID
     * @param userId 用户ID（用于权限验证）
     * @throws BusinessException 如果商品不存在或用户无权限删除
     */
    @Override
    @Transactional
    public void deleteProduct(Integer productId, Integer userId) {
        // 检查商品是否存在及权限
        Product product = productMapper.findById(productId);
        if (product == null || !product.getUserId().equals(userId)) {
            throw new BusinessException("商品不存在或无权删除");
        }

        // 删除商品记录
        productMapper.delete(productId, userId);

        // 删除商品图片信息
        productImageMapper.deleteByProductId(productId);
    }

    /**
     * 根据ID获取商品详情（包含图片）
     * @param productId 商品ID
     * @return 商品实体
     * @throws BusinessException 如果商品不存在
     */
    @Override
    public Product getProductById(Integer productId) {
        Product product = productMapper.findById(productId);
        if (product == null) {
            throw new BusinessException("商品不存在");
        }

        // 查询并设置商品图片
        List<ProductImage> images = productImageMapper.findByProductId(productId);
        product.setImages(images);
        return product;
    }

    /**
     * 获取所有可用商品列表（包含图片）
     * @return 商品列表
     */
    @Override
    public List<Product> getAllProducts() {
        List<Product> products = productMapper.findAllAvailable();
        // 为每个商品查询并设置图片
        products.forEach(product -> {
            List<ProductImage> images = productImageMapper.findByProductId(product.getProductId());
            product.setImages(images);
        });
        return products;
    }

    /**
     * 获取指定用户的所有商品（包含图片）
     * @param userId 用户ID
     * @return 该用户的商品列表
     */
    @Override
    public List<Product> getUserProducts(Integer userId) {
        List<Product> products = productMapper.findByUserId(userId);
        // 为每个商品查询并设置图片
        products.forEach(product -> {
            List<ProductImage> images = productImageMapper.findByProductId(product.getProductId());
            product.setImages(images);
        });
        return products;
    }

    /**
     * 根据关键词搜索商品（包含图片）
     * @param keyword 搜索关键词
     * @return 匹配的商品列表
     */
    @Override
    public List<Product> searchProducts(String keyword) {
        List<Product> products = productMapper.searchByKeyword(keyword);
        // 为每个商品查询并设置图片
        products.forEach(product -> {
            List<ProductImage> images = productImageMapper.findByProductId(product.getProductId());
            product.setImages(images);
        });
        return products;
    }

    /**
     * 保存商品图片到本地目录并记录到数据库
     * @param images 上传的图片文件列表
     * @param productId 关联的商品ID
     * @return 保存成功的图片实体列表
     * @throws RuntimeException 当文件操作失败时抛出
     */
    @Override
    @Transactional
    public List<ProductImage> saveProductImages(List<MultipartFile> images, Integer productId) {
        List<ProductImage> savedImages = new ArrayList<>();
        if (images == null || images.isEmpty()) return savedImages;

        // 配置上传路径（项目根目录下的uploads文件夹）
        Path uploadPath = Paths.get("uploads");
        try {
            // 确保上传目录存在
            if (!Files.exists(uploadPath)) {
                Files.createDirectories(uploadPath);
                System.out.println("创建上传目录：" + uploadPath.toAbsolutePath());
            }

            // 处理每个图片文件
            for (MultipartFile image : images) {
                if (image.isEmpty()) continue;

                // 生成唯一文件名（UUID + 原始文件扩展名）
                String extension = StringUtils.getFilenameExtension(image.getOriginalFilename());
                String filename = UUID.randomUUID() + "." + extension;

                // 保存文件到本地
                Path targetPath = uploadPath.resolve(filename);
                image.transferTo(targetPath);

                // 记录访问路径（示例：http://localhost:8080/uploads/filename）
                System.out.println("文件保存路径：" + targetPath.toAbsolutePath());
                System.out.println("访问路径应该为：http://localhost:8080/uploads/" + filename);

                // 创建图片记录
                ProductImage productImage = new ProductImage();
                productImage.setProductId(productId);
                productImage.setImageUrl("uploads/" + filename); // 存储相对路径
                productImageMapper.insert(productImage);
                savedImages.add(productImage);
            }
        } catch (IOException e) {
            throw new RuntimeException("文件操作失败：" + e.getMessage());
        }

        return savedImages;
    }
}